import { BNode } from '../type/BNode';
import { IEvent } from '../type/IEvent';
import { TaskState } from '../type/TaskState';

/**
 * 选择树
 * 每次只执行一个节点,如果这个节点执行完毕,就执行下一个节点,直到所有节点执行完毕
 * 如果有一个返回错误,跳过继续执行其他节点
 */
export class SelectTree extends BNode implements IEvent {
    public children: IEvent[] = [];

    private index: number = 0;
    private iTime: number = 0;

    addChild(...nodes: IEvent[]) {
        for (const n of nodes) {
            this.children.push(n);
        }
    }

    onUpdate(dt: number): void {
        if (this.getState() != TaskState.running) {
            return;
        }
        this.iTime += dt;
        const node = this.children[this.index];
        //遇到错误,跳过执行
        if (node.task.getState() == TaskState.error) {
            this.index++;
            this.onUpdate(0);
        }
        if (node.task.getState() === TaskState.pending) {
            node.task.running();
            node.onStart(this.blackBoard);
        }
        if (node.task.getState() === TaskState.running) {
            node.onUpdate(dt);
        }
        if (node.task.getState() === TaskState.done) {
            this.index++;
            if (this.index >= this.children.length) {
                this.task.done();
                return;
            }
            this.onUpdate(0); //递归调用
        }
    }

    onCancel(): void {
        this.task.error();
        this.index = 0;
    }

    getState(): TaskState {
        return this.task.getState();
    }

    onReset(): void {
        this.index = 0;
        this.children.forEach((value) => {
            value.task.reset();
            value.onReset();
        });
        this.task.done();
    }

    onEvent(event: string, data?: any): void {
        for (let i = 0; i < this.children.length; i++) {
            this.children[i].onEvent(event, data);
        }
    }
}
